
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.util.ResourceBundle;

/**
 * <p>
 * Interface grafica simples para o simulador de elevadores.
 * </p>
 */
class InterfaceDeUsuarioSimples implements IInterfaceDeUsuario {

  ///////////////////////////////////////
  // attributes


/**
 * <p>
 * Representa os rotulos a serem usados na interface de acordo com a sua
 * localizacao. Se nenhum parametro for colocado na linha de comando que
 * dispara a execucao do Simulador de Elevadores, entao a interface usa
 * rotulos em Portugues. Para usar rotulos em Ingles, por exemplo, o comando
 * </p>
 * <p>
 * %java SimuladorDeElevadores en US
 * </p>
 * <p>
 * deve ser dado, onde o primeiro argumento representa a lingua (en -
 * Ingles) e o segundo o pais (US - Estados Unidos). Os rotulos em Ingles
 * se encontram em Rotulos_en_US.properties. Os de Portugues do Brasil em
 * Rotulos_pt_BR.properties. Tais arquivos devem estar no mesmo diretorio
 * em que se encontrar o arquivo SimuladorDeElevadores.class.
 * </p>
 */
    private ResourceBundle rotulos; 

/**
 * <p>
 * Representa o numero de andares do predio.
 * </p>
 */
    private int numAndares; 

/**
 * <p>
 * Representa o numero de elevadores no predio.
 * </p>
 */
    private int numElevadores; 

/**
 * <p>
 * Representa a janela principal da aplicacao.
 * </p>
 */
    private Frame janela; 

/**
 * <p>
 * Cadeia de caracteres que representa a Porta aberta.
 * </p>
 */
    public static final String portaAberta = "[  ]"; 

/**
 * <p>
 * Cadeia de caracteres que representa a Porta fechada.
 * </p>
 */
    public static final String portaFechada = " ][ "; 

/**
 * <p>
 * Cadeia de caracteres que representa a presenca do Elevador em um
 * particular andar.
 * </p>
 */
    public static final String elevadorPresente = " ++ "; 

/**
 * <p>
 * Cadeia de caracteres que representa a ausencia do Elevador em um
 * particular andar.
 * </p>
 */
    public static final String elevadorAusente = " -- "; 

   ///////////////////////////////////////
   // associations

/**
 * <p>
 * Representa a interface de software do controlador do sistema de
 * elevadores com o qual a interface de usuario interage.
 * </p>
 */
    public IControlador iControlador; 
/**
 * <p>
 * Colecao das representacoes graficas das instancias de BotaoDeRequisicao
 * instaladas nos andares.
 * </p>
 */
    private ArrayList<ArranjoBotaoExternoAndar> arranjoBotaoExternoAndar = new ArrayList<ArranjoBotaoExternoAndar>();
/**
 * <p>
 * Colecao das representacoes graficas das instancias Elevador pertencentes
 * ao Predio.
 * </p>
 */
    public ArrayList<RepresentacaoElevador> representacaoElevador = new ArrayList<RepresentacaoElevador>();


  ///////////////////////////////////////
  // operations


/**
 * <p>
 * Cria uma instancia de InterfaceDeUsuarioSimples.
 * </p>
 * 
 * @return uma instancia de InterfaceDeUsuarioSimples.
 * 
 * @param iControlador - interface de software do Controlador com o qual a
 * InterfaceDeUsuarioSimples vai interagir.
 * 
 * @param rotulos 
 * @param numAndares - numero de andares do predio.
 * 
 * @param numElevadores - numero de elevadores instalados no predio.
 * 
 * @param andarInicial - andar em que se localizam os elevadores quando se
 * inicia a aplicacao.
 * 
 * @param portaFechada - true se a Porta de todos os elevadores estiver
 * fechada ao se iniciar a aplicacao.
 */
    public  InterfaceDeUsuarioSimples(IControlador iControlador, ResourceBundle rotulos, int numAndares, int numElevadores, int andarInicial, boolean portaFechada) {        
        int andar, elevador;
        ArranjoBotaoExternoAndar arranjoBotaoExterno;
        RepresentacaoElevador representacaoElevadorCorrente;
        Panel panelBotoesExternosAndares, panelElevadores;
        GridLayout gridJanela, gridBotoesExternosAndares, gridTodosElevadores;
        this.iControlador = iControlador;
        this.rotulos = rotulos;
        this.numAndares = numAndares;
        this.numElevadores = numElevadores;
        janela = new Frame(rotulos.getString("rotuloJanela"));
        janela.addWindowListener(
            new WindowAdapter() {
                public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
        gridJanela = new GridLayout(1, numElevadores + 1);
        janela.setLayout(gridJanela);
        gridBotoesExternosAndares = new GridLayout(numAndares + 1, 1, 0, 10);
        panelBotoesExternosAndares = new Panel(gridBotoesExternosAndares);
        panelBotoesExternosAndares.add(new Label(rotulos.getString("botoesAndar"), Label.CENTER));
        arranjoBotaoExternoAndar.ensureCapacity(numAndares + 1);
        arranjoBotaoExternoAndar.add(0, null);
        for (andar = 1; andar <= numAndares; andar++) {
            arranjoBotaoExterno = new ArranjoBotaoExternoAndar(this, andar, numAndares);
            arranjoBotaoExternoAndar.add(andar, arranjoBotaoExterno);
        }
        for (andar = numAndares; andar >= 1; andar--) {
            arranjoBotaoExterno = arranjoBotaoExternoAndar.get(andar);
            panelBotoesExternosAndares.add(arranjoBotaoExterno.getPanel());
        }
        janela.add(panelBotoesExternosAndares);
        gridTodosElevadores = new GridLayout(1, numElevadores);
        panelElevadores = new Panel(gridTodosElevadores);
        representacaoElevador.ensureCapacity(numElevadores + 1);
        representacaoElevador.add(0, null);
        for (elevador = 1; elevador <= numElevadores; elevador++) {
            representacaoElevadorCorrente = new RepresentacaoElevador(this, rotulos, elevador, numAndares, andarInicial, portaFechada);
            representacaoElevador.add(elevador, representacaoElevadorCorrente);
            panelElevadores.add(representacaoElevadorCorrente.getPanel());
        }
        
        janela.add(panelElevadores);
        janela.pack();
        janela.setVisible(true);
    } // end InterfaceDeUsuarioSimples        

/**
 * <p>
 * Registra nova posicao do Elevador indicado.
 * </p>
 * 
 * @param indElevador - indicador do Elevador cuja posicao se alterou.
 * 
 * @param andar - nova posicao do Elevador indicado.
 */
    public void registrarPosicaoElevador(int indElevador, int andar) {        
        getRepresentacaoElevador(indElevador).registrarPosicaoElevador(andar);
    } // end registrarPosicaoElevador        

/**
 * <p>
 * Registra o estado da Porta do Elevador indicado.
 * </p>
 * 
 * @param indElevador - indicador do Elevador envolvido.
 * 
 * @param fechada - true se a Porta do Elevador esta' sendo informada como
 * fechada.
 */
    public void registrarEstadoPorta(int indElevador, boolean fechada) {        
        getRepresentacaoElevador(indElevador).registrarEstadoPorta(fechada);
    } // end registrarEstadoPorta        

/**
 * <p>
 * Recebe a solicitacao de representar na InterfaceDeUsuarioSimples que o
 * BotaoDeSelecao do Elevador indicado e representante de uma particular
 * andar foi armado.
 * </p>
 * 
 * @param indElevador - indicador do Elevador envolvido.
 * 
 * @param andar - andar associado ao Botao.
 */
    public void armarBotaoSelecao(int indElevador, int andar) {        
        getRepresentacaoElevador(indElevador).armarBotaoSelecao(andar);
    } // end armarBotaoSelecao        

/**
 * <p>
 * Recebe a solicitacao de representar na InterfaceDeUsuarioSimples que o
 * BotaoDeSelecao do Elevador indicado e representante de uma particular
 * andar foi desarmado.
 * </p>
 * 
 * @param indElevador - indicador do Elevador envolvido.
 * 
 * @param andar - andar associado ao Botao.
 */
    public void desarmarBotaoSelecao(int indElevador, int andar) {        
        getRepresentacaoElevador(indElevador).desarmarBotaoSelecao(andar);
    } // end desarmarBotaoSelecao        

/**
 * <p>
 * Recebe a solicitacao de representar na InterfaceDeUsuarioSimples que o
 * BotaoDeRequisicao indicador da intencao do Passageiro em locomover-se
 * para cima e instalado no andar informado foi armado.
 * </p>
 * 
 * @param andar - andar em que se encontra instalado o Botao.
 */
    public void armarBotaoSubida(int andar) {        
        getArranjoBotaoExternoAndar(andar).armarBotaoDeRequisicao(true);
    } // end armarBotaoSubida        

/**
 * <p>
 * Recebe a solicitacao de representar na InterfaceDeUsuarioSimples que o
 * BotaoDeRequisicao indicador da intencao do passageiro em locomover-se
 * para cima e instalado no andar informado foi desarmado.
 * </p>
 * 
 * @param andar - andar em que se encontra instalado o Botao.
 */
    public void desarmarBotaoSubida(int andar) {        
        getArranjoBotaoExternoAndar(andar).desarmarBotaoDeRequisicao(true);
    } // end desarmarBotaoSubida        

/**
 * <p>
 * Recebe a solicitacao de representar na InterfaceDeUsuarioSimples que o
 * BotaoDeRequisicao indicador da intencao do Passageiro em locomover-se
 * para baixo e instalado no andar informado foi armado.
 * </p>
 * 
 * @param andar - andar em que se encontra instalado o Botao.
 */
    public void armarBotaoDescida(int andar) {        
        getArranjoBotaoExternoAndar(andar).armarBotaoDeRequisicao(false);
    } // end armarBotaoDescida        

/**
 * <p>
 * Recebe a solicitacao de representar na InterfaceDeUsuario que o
 * BotaoDeRequisicao indicador da intencao do passageiro em locomover-se
 * para baixo e instalado no andar informado foi desarmado.
 * </p>
 * 
 * @param andar - andar em que se encontra instalado o Botao.
 */
    public void desarmarBotaoDescida(int andar) {        
        getArranjoBotaoExternoAndar(andar).desarmarBotaoDeRequisicao(false);
    } // end desarmarBotaoDescida        

/**
 * <p>
 * Recebe a informacao de que a representacao de um BotaoDeRequisicao
 * instalado no andar indicado e representante de uma determinada intencao
 * de locomocao foi acionada na InterfaceDeUsuarioSimples.
 * </p>
 * 
 * @param andar - andar em que se encontra instalado o BotaoDeRequisicao.
 * 
 * @param subir - representa a intencao de direcao de locomocao associada
 * ao Botao.
 */
    public void registrarAcionamentoBotaoDeRequisicao(int andar, boolean subir) {        
        if (subir) iControlador.registrarBotaoSubidaAcionado(andar);
        else iControlador.registrarBotaoDescidaAcionado(andar);
    } // end registrarAcionamentoBotaoDeRequisicao        

/**
 * <p>
 * Recebe a informacao de que a representacao de um BotaoDeSelecao
 * instalado no Elevador indicado e representante do andar apontado foi
 * acionada na InterfaceDeUsuarioSimples.
 * </p>
 * 
 * @param indElevador - indicador do Elevador envolvido.
 * 
 * @param andar - andar representado pelo Botao.
 */
    public void registrarAcionamentoBotaoDeSelecao(int indElevador, int andar) {        
        iControlador.registrarBotaoDeSelecaoAcionado(indElevador, andar);
    } // end registrarAcionamentoBotaoDeSelecao        

/**
 * <p>
 * Retorna o conjunto de representacoes graficas (ArranjoBotaoExternoAndar)
 * das instancias de BotaoDeRequisicao instalados no andar indicado.
 * </p>
 * 
 * @return uma instancia de ArranjoBotaoExternoAndar.
 * 
 * @param andar - andar em que se encontram instalados os botoes
 * representados na InterfaceDeUsuarioSimples.
 */
    private ArranjoBotaoExternoAndar getArranjoBotaoExternoAndar(int andar) {        
        return arranjoBotaoExternoAndar.get(andar);
    } // end getArranjoBotaoExternoAndar        

/**
 * <p>
 * Retorna a representacao grafica (RepresentacaoElevador) do Elevador
 * indicado.
 * </p>
 * 
 * @return uma instancia de EstadoElevador.
 * 
 * @param indElevador - indicador do Elevador envolvido.
 */
    private RepresentacaoElevador getRepresentacaoElevador(int indElevador) {        
        return representacaoElevador.get(indElevador);
    } // end getRepresentacaoElevador        



    /**
     * <p>
     * Recebe a solicitacao de representar na InterfaceDeUsuarioSimples que o
     * BotaoDeEmergencia do Elevador indicado e foi armado.
     * </p>
     * 
     * @param indElevador - indicador do Elevador envolvido.
     */
        public void armarBotaoDeEmergencia(int indElevador) {        
            getRepresentacaoElevador(indElevador).armarBotaoDeEmergencia();
        } // end armarBotaoSelecao        


    /**
     * <p>
     * Recebe a solicitacao de representar na InterfaceDeUsuarioSimples que o
     * BotaoDeEmergencia do Elevador indicado e representante foi desarmado.
     * </p>
     * 
     * @param indElevador - indicador do Elevador envolvido.
     */
        public void desarmarBotaoDeEmergencia(int indElevador) {        
            getRepresentacaoElevador(indElevador).desarmarBotaoDeEmergencia();
        } // end desarmarBotaoSelecao        


    /**
     * <p>
     * Recebe a informacao de que a representacao de um BotaoDeEmergencia
     * instalado no Elevador indicado foi
     * acionada na InterfaceDeUsuarioSimples.
     * </p>
     * 
     * @param indElevador - indicador do Elevador envolvido.
     */
        public void registrarAcionamentoBotaoDeEmergencia(int indElevador) {        
            iControlador.registrarBotaoDeEmergenciaAcionado(indElevador);
        } // end registrarAcionamentoBotaoDeSelecao        


    
} // end InterfaceDeUsuarioSimples



